/*
 * @Author: llch
 * @Date: 2020-06-12 10:33:19
 * @LastEditTime: 2020-06-19 16:08:02
 * @LastEditors: Please set LastEditors
 * @Description: 游戏主逻辑
 * @FilePath: \man_demo\assets\Script\Game.ts
 */ 

import { ResourcesList } from "./Config/Config"
import { Res } from "./Res"
import { Item } from "./Category/Item"
import { Option } from "./SelectArea/Option";
import { Player } from "./Player/Player";
 
const {ccclass, property} = cc._decorator;

@ccclass
export class Game extends cc.Component {

    @property(cc.Prefab)
    public categoryItem: cc.Prefab = null;
    @property(cc.ScrollView)
    public categoryScrollView: cc.ScrollView = null;

    // ==============进度条start=============================
    @property(cc.Node)
    public loadingNode: cc.Node = null;
    @property(cc.ProgressBar)
    public progressbar: cc.Node = null;
    @property(cc.Label)
    public progressLabel: cc.Label = null;
    public comDegress: number = 0;  // 完成度
    public comFlag = false;         // 完成标志
    public proBar: cc.ProgressBar = null;
    public nowTime: number = 0;
    public allTime: number = 10;
    // ==============进度条end=============================

    @property(Res)
    public res: Res = null;

    @property(cc.Node)                          // 选择区节点
    public selectAreaNode: cc.Node = null;
    @property(cc.Node)                          // 皮肤选择区
    public skincolor: cc.Node = null; 

    public itemArr = [];                        // 目录菜单中的每个item
    public scrollViewArr = [];                  // 每个目录下对应的 滑动区域
    public firstOptionMap = new Map();          // 每个分类下的 第一项

    @property(Player)
    public Player: Player = null;

    @property(cc.Animation)
    public canvasAni: cc.Animation = null;

    public nowPlay: string = "-1";

    onLoad () {
        /** ----进度条---- */
        this.proBar = this.progressbar.getComponent(cc.ProgressBar);    // 进度条组件
        this.initTime();
        this.loadSource();
        this.comDegress = 0;
        this.comFlag = false;

        /** ----皮肤分类初始化---- */
        this.scrollViewArr.push(this.skincolor);
        let n: cc.Node = this.skincolor.getComponent(cc.ScrollView).content;
        for (let s = 0; s < n.childrenCount; s++) {
            n.children[s].on('toggle', this.onSkinBtnClick, this)
        }

        /** ----初始化剩余分类---- */
        this.categoryScrollView.content.removeAllChildren();
        for (let i = 0; i < ResourcesList.length; i++) {
            let node = cc.instantiate(this.categoryItem);
            node.parent = this.categoryScrollView.content;

            let item: Item = node.getComponent(Item);
            this.itemArr.push(item);
            item.setCategoryImg(this.res.spriteframeArr[i], ResourcesList[i].id);

            node.on('toggle', this.onCategoryClick, this);

            // 除了皮肤分类以外
            if (i !== 0) {
                let sc = cc.instantiate(this.res.scrollViewPre);
                sc.name = ResourcesList[i].name;
                sc.parent = this.selectAreaNode;
                this.scrollViewArr.push(sc);
            }
        }

        /** 单独设置bg分类 */
        let bgscorllView = cc.instantiate(this.res.scrollViewPre);
        bgscorllView.parent = this.selectAreaNode;
        this.scrollViewArr.push(bgscorllView);

        /** ----默认选中皮肤分类---- */
        this.skincolor.active = true;
        /** ----设置初始人物颜色---- */
        this.Player.changePlayerColor(new cc.Color(254, 233, 228, 255));
    }

    /**
     * @description: 分类回调事件
     * @param {type} 
     * @return: 
     */
    public onCategoryClick(e) {
        let index = e.target.parent.getComponent(Item).index;
        for (let i = 0; i < ResourcesList.length; i++) {
            if (i === index) {
                // 初始化分类所属选择区数据
                this.initSelectData(i);
                this.showSelectArea(i);
            } else {
                this.hideSelectArea(i);
            }
        }
    }

    /**
     * @description: 显示分类对应的选择区
     * @param {number} index:分类id
     * @return: 
     */
    public showSelectArea(index: number) {
        // 发型分类 显示 修改颜色节点
        if (index === 1) {
            this.res.colorNode.active = true;
        } else {
            this.res.colorNode.active = false;
        }
        this.scrollViewArr[index].active = true;
        this.scrollViewArr[index].getComponent(cc.ScrollView).scrollToTop(0.1);
    }

    /**
     * @description: 隐藏分类对应的选择区
     * @param {number} index:分类id
     * @return: 
     */
    public hideSelectArea(index: number) {
        this.scrollViewArr[index].active = false;
    }

    /**
     * @description: 人物皮肤回调
     */
    public onSkinBtnClick(e) {
        let color: cc.Color = e.target.parent.color;
        this.Player.changePlayerColor(color);
    }

/** ========================================初始化选择区数据============================================== **/
    /**
     * @description: 初始化每个分类对应选择区的数据
     * @param {number} index: 分类id 
     * @return: 
     */
    public initSelectData(index: number) {
        // 过滤掉皮肤分类 或者 该分类数据已加载过
        if (index === 0 || this.itemArr[index].data !== null) {
            return;
        }
        let url = "character/" + ResourcesList[index].name;
        if (index === 16) {
            cc.loader.loadResDir(url, cc.SpriteFrame, (err, sfs)=>{
                if (err) {
                    cc.error(err);
                    return;
                }
                // 取出所有精灵数据，存入map
                let map = new Map();
                for (let m = 0; m < sfs.length; m++) {
                    let name = sfs[m].name.toString();
                    map.set(name, sfs[m]);
                }
                this.itemArr[index].data = map;
    
                // 初始化当前分类下选择区的选项
                this.initCategoryOptions(map, index);
            });
            return;
        }
        cc.loader.loadResDir(url, cc.SpriteAtlas, (err, atlas)=>{
            if (err) {
                cc.error(err);
                return;
            }
            let arr = [];
            for (let a = 0; a < atlas.length; a++) {
                arr = arr.concat(atlas[a].getSpriteFrames())
            }
            // 取出所有精灵数据，存入map
            let map = new Map();
            for (let m = 0; m < arr.length; m++) {
                let name = arr[m].name.toString();
                map.set(name, arr[m]);
            }
            this.itemArr[index].data = map;

            // 初始化当前分类下选择区的选项
            this.initCategoryOptions(map, index);
        });
    }

    // 选项初始化
    /**
     * @description: 初始化选择区选项
     * @param {map} map: 保存精灵的map 
     * @param {number} index: 分类id
     * @return: 
     */
    public initCategoryOptions(map, index) {
        let nowScrollView = this.scrollViewArr[index].getComponent(cc.ScrollView);
        let typeName = ResourcesList[index].name;
        
        // 第一项拿出来单独处理
        let k = typeName + "_0";
        let v = map.get(k);
        let node = cc.instantiate(this.res.optionPre);
        node.name = k;
        let option: Option = node.getComponent(Option);
        let ownerSf = null;
        let ownerSkin = null;
        option.goods.getComponent(cc.Sprite).spriteFrame = v;
        ownerSf = v;
        // 初始化选项数据
        option.initOption(index, ownerSf, ownerSkin, typeName);
        // 默认选中每个分类的第一项
        let tg = node.getComponent(cc.Toggle);
        tg.isChecked = true;
        // 保存每个分类里的第一项
        this.firstOptionMap.set(k, tg);
        // 添加监听
        node.on('toggle', this.onOptionClick, this);
        node.parent = nowScrollView.content;

        map.forEach((value, key) => {
            if (key.indexOf("_0") !== -1) {
                // 跳过第一个
            } else {
                if (key.indexOf("skin") === -1) {
                    let node = cc.instantiate(this.res.optionPre);
                    node.name = key;
                    let option: Option = node.getComponent(Option);
                    let ownerSf = null;
                    let ownerSkin = null;
                    option.goods.getComponent(cc.Sprite).spriteFrame = value;
                    ownerSf = value;
                    let str = key + "_skin";
                    let ssf = map.get(str);
                    if (ssf) {
                        option.skin.getComponent(cc.Sprite).spriteFrame = ssf;
                        ownerSkin = ssf;
                    }
                    // 初始化选项数据
                    option.initOption(index, ownerSf, ownerSkin, typeName);
                    // 添加监听
                    node.on('toggle', this.onOptionClick, this);
                    node.parent = nowScrollView.content;
                }
            }
        });
    }
    
/** ========================================换装============================================== **/
    /**
     * @description: 选择区每个选项的回调
     */
    public onOptionClick(e) {
        let option: Option = e.target.parent.getComponent(Option);
        let index = option.index;
        let ownerSf = option.ownerSf;
        let ownerSkin = option.ownerSkin;
        let categoryName = option.categoryName;

        let flag = false;       // flag 用来表示全身装扮 是否在使用
        if (!e.isChecked || e.node.name === (categoryName + "_0")) {     // 选中取消 则默认回到第一个位置
            let tg = this.firstOptionMap.get(categoryName + "_0");
            tg.isChecked = true;
            if (index !== 16) {
                ownerSf = null;
                ownerSkin = null;
            } else {
                ownerSf = this.itemArr[index].data.get(categoryName + "_0");
            }
            flag = true;
        }

        // 判断插入到哪
        switch (index) {
            case 1:
                this.Player.changeHair(ownerSf, ownerSkin);
                break;
            case 2:
                this.Player.changeEye(ownerSf);
                break;
            case 3:
                this.Player.changeEyebrow(ownerSf);
                break;
            case 4:
                this.Player.changeMouse(ownerSf);
                break;
            case 5:
                this.Player.changeTopClothes(ownerSf);
                break;
            case 7:
                this.Player.changeBottomClothes(ownerSf);
                break;
            case 9:
                this.Player.changeShoes(ownerSf);
                break;
            case 10:
                this.Player.changeBlusher(ownerSf);
                break;
            case 11:
                this.Player.changeAccessory(ownerSf);
                break;
            case 12:
                this.Player.changeWing(ownerSf);
                break;
            case 13:
                this.Player.changeBag(ownerSf);
                break;
            case 6:         // coat
                this.Player.changeCoat(ownerSf, ownerSkin, cc.v2(0, 30));
                break;
            case 8:         // wholebodyclothes
                this.Player.changeWholebodyclothes(ownerSf, ownerSkin, flag);
                break;
            case 14:        // animalclothes
                this.Player.changeCoat(ownerSf, ownerSkin, cc.v2(0, 22));
                break;
            case 15:        // christmasclothes
                this.Player.changeChristmasclothes(ownerSf, ownerSkin, flag);
                break;
            case 16:
                this.Player.changeBg(ownerSf);
                break;
            default:
                cc.error("set err");
        }
    }

    /**
     * @description: 人物皮肤颜色回调
     */
    public onHairColorClick(e) {
        let color: cc.Color = e.target.color;
        this.Player.changeHairColor(color);
    }

/** ========================================btn============================================== **/
    public onSaveClick(e, c) {
        if (c === this.nowPlay) {
            return;
        }
        this.nowPlay = "1";
        this.canvasAni.play("hide");
    }

    public onNoClick(e, c) {
        if (c === this.nowPlay) {
            return;
        }
        this.nowPlay = "0";
        this.canvasAni.play("show");
    }

/** ========================================进度条============================================== **/
    public initTime() {
        this.nowTime = 0;       // 当前已经过去得时间
        this.allTime = 10;      // 总时间
    }

    public loadSource() {
        cc.loader.loadResDir("character", (compCount, totalCount, item)=>{
            // 进度条回调
            this.comDegress = compCount / totalCount;
        }, (err, assets, urls)=>{
            if (err) {
                cc.error("load sources is err");
            }
            this.comFlag = true;
            this.loadingNode.active = false;
        });
    }

    update(dt) {
        if(this.comFlag) {
            //
        } else {
            this.proBar.progress = this.comDegress;
            let now = this.comDegress * 100;
            this.progressLabel.string = parseInt(now.toString()) + "%";
        }
    }
}